package com.blog.cmrpersonalblog.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blog.cmrpersonalblog.dto.article.request.ArticleQueryRequest;
import com.blog.cmrpersonalblog.dto.article.response.ArticleManagementResponse;
import com.blog.cmrpersonalblog.dto.article.response.ArticleDetailResponse;
import com.blog.cmrpersonalblog.dto.article.request.UserArticleQueryRequest;
import com.blog.cmrpersonalblog.dto.homepage.HomePageResponse;
import com.blog.cmrpersonalblog.dto.homepage.HomePageQueryRequest;
import com.blog.cmrpersonalblog.dto.article.response.UserArticleDetailResponse;
import com.blog.cmrpersonalblog.dto.ranking.respnose.RankingArticleInfo;
import com.blog.cmrpersonalblog.dto.tag.respnose.TagInfo;
import com.blog.cmrpersonalblog.dto.user.response.UserProfileResponse;
import com.blog.cmrpersonalblog.entity.Article;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

/**
 * 文章Mapper接口
 */
public interface ArticleMapper extends BaseMapper<Article> {

    /**
     * 分页查询用户文章列表
     * @param page 分页对象
     * @param query 查询条件
     * @return 文章列表
     */
    IPage<UserProfileResponse.ArticleInfo> selectUserArticlePage(Page<UserProfileResponse.ArticleInfo> page, 
                                                                  @Param("query") UserArticleQueryRequest query);

    /**
     * 获取用户最近发布的文章
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 文章列表
     */
    List<UserProfileResponse.ArticleInfo> selectRecentArticlesByUserId(@Param("userId") Long userId,
                                                                        @Param("limit") Integer limit);

    /**
     * 获取用户最新发布的文章（用于展示）
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 文章列表
     */
    List<UserProfileResponse.ArticleInfo> selectUserLatestArticles(@Param("userId") Long userId,
                                                                    @Param("limit") Integer limit);

    /**
     * 获取用户最热文章（按浏览量排序，用于展示）
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 文章列表
     */
    List<UserProfileResponse.ArticleInfo> selectUserHotArticles(@Param("userId") Long userId,
                                                                 @Param("limit") Integer limit);

    /**
     * 分页查询用户文章展示列表（支持按最新或最热排序）
     * @param page 分页对象
     * @param userId 用户ID
     * @param sortType 排序类型：latest-最新，hot-最热
     * @return 文章分页列表
     */
    IPage<UserProfileResponse.ArticleInfo> selectUserArticleShowcasePage(Page<UserProfileResponse.ArticleInfo> page,
                                                                          @Param("userId") Long userId,
                                                                          @Param("sortType") String sortType);

    /**
     * 根据文章ID查询标签信息列表
     * @param articleId 文章ID
     * @return 标签信息列表
     */
    List<TagInfo> selectTagInfoByArticleId(@Param("articleId") Long articleId);

    /**
     * 分页查询首页文章列表
     * @param page 分页对象
     * @param query 查询条件
     * @return 文章列表
     */
    IPage<Map<String, Object>> selectHomeArticlePage(Page<Map<String, Object>> page,
                                                      @Param("query") HomePageQueryRequest query);

    /**
     * 获取热门文章榜单（按浏览量）
     * @param limit 限制数量
     * @return 热门文章列表
     */
    List<RankingArticleInfo> selectHotArticleRanking(@Param("limit") Integer limit);

    /**
     * 获取点赞文章榜单（按点赞数）
     * @param limit 限制数量
     * @return 点赞文章列表
     */
    List<RankingArticleInfo> selectLikedArticleRanking(@Param("limit") Integer limit);

    /**
     * 获取最新文章榜单（按发布时间）
     * @param limit 限制数量
     * @return 最新文章列表
     */
    List<RankingArticleInfo> selectLatestArticleRanking(@Param("limit") Integer limit);

    /**
     * 统计用户文章数据
     * @param userId 用户ID
     * @return 统计数据
     */
    UserProfileResponse.UserStatsInfo selectUserArticleStats(@Param("userId") Long userId);

    /**
     * 更新文章统计数据
     * @param articleId 文章ID
     * @param field 字段名
     * @param increment 增量
     */
    void updateArticleStats(@Param("articleId") Long articleId,
                           @Param("field") String field,
                           @Param("increment") Integer increment);

    // ==================== 文章管理相关方法 ====================

    /**
     * 分页查询文章管理列表
     * @param page 分页对象
     * @param query 查询条件
     * @return 文章管理列表
     */
    IPage<ArticleManagementResponse> selectArticleManagementPage(Page<ArticleManagementResponse> page,
                                                                 @Param("query") ArticleQueryRequest query);

    /**
     * 获取文章详情（包含作者和分类信息）
     * @param articleId 文章ID
     * @return 文章详情
     */
    ArticleDetailResponse selectArticleDetailById(@Param("articleId") Long articleId);

    /**
     * 批量更新文章状态
     * @param articleIds 文章ID列表
     * @param status 目标状态
     * @param operatorId 操作人ID
     * @return 更新数量
     */
    int batchUpdateArticleStatus(@Param("articleIds") List<Long> articleIds,
                                @Param("status") Integer status,
                                @Param("operatorId") Long operatorId);

    /**
     * 批量更新文章置顶状态
     * @param articleIds 文章ID列表
     * @param isTop 是否置顶
     * @param operatorId 操作人ID
     * @return 更新数量
     */
    int batchUpdateArticleTop(@Param("articleIds") List<Long> articleIds,
                             @Param("isTop") Integer isTop,
                             @Param("operatorId") Long operatorId);

    /**
     * 批量删除文章
     * @param articleIds 文章ID列表
     * @param operatorId 操作人ID
     * @return 删除数量
     */
    int batchDeleteArticles(@Param("articleIds") List<Long> articleIds,
                           @Param("operatorId") Long operatorId);

    /**
     * 更新文章审核信息
     * @param articleId 文章ID
     * @param status 审核状态
     * @param auditUserId 审核人ID
     * @param auditRemark 审核备注
     * @param auditReason 审核原因
     * @return 更新数量
     */
    int updateArticleAuditInfo(@Param("articleId") Long articleId,
                              @Param("status") Integer status,
                              @Param("auditUserId") Long auditUserId,
                              @Param("auditRemark") String auditRemark,
                              @Param("auditReason") String auditReason);

    /**
     * 获取文章统计信息
     * @return 统计信息
     */
    @MapKey("field")
    Map<String, Object> selectArticleStatistics();

    /**
     * 获取待审核文章数量
     * @return 待审核数量
     */
    Long selectPendingAuditCount();

    /**
     * 获取文章状态分布
     * @return 状态分布
     */
    @MapKey("field")
    List<Map<String, Object>> selectArticleStatusDistribution();

    /**
     * 获取热门文章列表
     * @param limit 数量限制
     * @return 热门文章列表
     */
    List<ArticleManagementResponse> selectPopularArticles(@Param("limit") Integer limit);

    // ==================== 仪表盘统计功能 ====================

    /**
     * 统计今日新增文章数
     * @return 今日新增文章数
     */
    Long countTodayNewArticles();

    /**
     * 统计昨日新增文章数
     * @return 昨日新增文章数
     */
    Long countYesterdayNewArticles();

    /**
     * 统计指定日期范围内每日新增文章数
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 每日新增文章数列表
     */
    List<Map<String, Object>> countDailyNewArticles(@Param("startDate") String startDate, @Param("endDate") String endDate);

    /**
     * 统计指定日期范围内每日文章总数
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 每日文章总数列表
     */
    List<Map<String, Object>> countDailyTotalArticles(@Param("startDate") String startDate, @Param("endDate") String endDate);

    /**
     * 获取最新文章列表
     * @param limit 数量限制
     * @return 最新文章列表
     */
    List<ArticleManagementResponse> selectLatestArticles(@Param("limit") Integer limit);

    /**
     * 搜索文章
     * @param page 分页对象
     * @param keyword 关键词
     * @return 搜索结果
     */
    IPage<ArticleManagementResponse> searchArticles(Page<ArticleManagementResponse> page,
                                                   @Param("keyword") String keyword);

    /**
     * 获取用户文章管理列表
     * @param page 分页对象
     * @param userId 用户ID
     * @return 用户文章列表
     */
    IPage<ArticleManagementResponse> selectUserArticleManagementPage(Page<ArticleManagementResponse> page,
                                                                     @Param("userId") Long userId);

    /**
     * 获取分类文章管理列表
     * @param page 分页对象
     * @param categoryId 分类ID
     * @return 分类文章列表
     */
    IPage<ArticleManagementResponse> selectCategoryArticleManagementPage(Page<ArticleManagementResponse> page,
                                                                         @Param("categoryId") Long categoryId);

    /**
     * 重新计算文章统计数据
     * @param articleId 文章ID
     * @return 更新数量
     */
    int recalculateArticleStats(@Param("articleId") Long articleId);

    // ==================== 用户详情统计相关方法 ====================

    /**
     * 获取用户发布统计信息
     * @param userId 用户ID
     * @return 发布统计信息
     */
    Map<String, Object> selectUserPublishStats(@Param("userId") Long userId);

    /**
     * 获取用户分类统计
     * @param userId 用户ID
     * @return 分类统计列表
     */
    List<Map<String, Object>> selectUserCategoryStats(@Param("userId") Long userId);

    /**
     * 获取用户热门标签
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 热门标签列表
     */
    List<Map<String, Object>> selectUserTopTags(@Param("userId") Long userId, @Param("limit") Integer limit);

    /**
     * 统计用户草稿数
     * @param userId 用户ID
     * @return 草稿数
     */
    Integer countUserDrafts(@Param("userId") Long userId);

    /**
     * 统计用户已删除文章数
     * @param userId 用户ID
     * @return 已删除文章数
     */
    Integer countUserDeletedArticles(@Param("userId") Long userId);

    /**
     * 统计用户收到的点赞数（文章被点赞）
     * @param userId 用户ID
     * @return 收到的点赞数
     */
    Integer countUserReceivedLikes(@Param("userId") Long userId);

    /**
     * 统计用户给出的点赞数（用户点赞其他文章）
     * @param userId 用户ID
     * @return 给出的点赞数
     */
    Integer countUserGivenLikes(@Param("userId") Long userId);

    /**
     * 统计用户发出的评论数
     * @param userId 用户ID
     * @return 发出的评论数
     */
    Integer countUserGivenComments(@Param("userId") Long userId);

    /**
     * 统计用户收到的评论数（文章被评论）
     * @param userId 用户ID
     * @return 收到的评论数
     */
    Integer countUserReceivedComments(@Param("userId") Long userId);

    // ==================== 新增分页榜单查询方法 ====================

    /**
     * 分页查询热门文章榜单
     * @param page 分页对象
     * @return 热门文章榜单
     */
    IPage<RankingArticleInfo> selectHotArticleRankingPage(Page<RankingArticleInfo> page);

    /**
     * 分页查询点赞文章榜单
     * @param page 分页对象
     * @return 点赞文章榜单
     */
    IPage<RankingArticleInfo> selectLikedArticleRankingPage(Page<RankingArticleInfo> page);

    /**
     * 分页查询最新文章榜单
     * @param page 分页对象
     * @return 最新文章榜单
     */
    IPage<RankingArticleInfo> selectLatestArticleRankingPage(Page<RankingArticleInfo> page);

    /**
     * 根据文章ID查询排行榜文章信息
     * @param articleId 文章ID
     * @return 排行榜文章信息
     */
    RankingArticleInfo selectRankingArticleById(@Param("articleId") Long articleId);

    /**
     * 统计热门文章数量
     * @return 热门文章数量
     */
    Long countHotArticles();

    /**
     * 统计点赞文章数量
     * @return 点赞文章数量
     */
    Long countLikedArticles();

    /**
     * 统计最新文章数量
     * @return 最新文章数量
     */
    Long countLatestArticles();

    // ==================== 用户端文章查看相关方法 ====================

    /**
     * 获取用户端文章详情（包含作者、分类等完整信息）
     * @param articleId 文章ID
     * @return 用户端文章详情
     */
    UserArticleDetailResponse selectUserArticleDetail(@Param("articleId") Long articleId);

    /**
     * 获取相关文章推荐
     * @param articleId 当前文章ID
     * @param limit 推荐数量
     * @return 相关文章列表
     */
    List<UserArticleDetailResponse.RelatedArticleInfo> selectRelatedArticles(@Param("articleId") Long articleId, @Param("limit") Integer limit);

    /**
     * 增加文章浏览量
     * @param articleId 文章ID
     * @return 更新数量
     */
    int incrementViewCount(@Param("articleId") Long articleId);

    /**
     * 增加文章点赞数
     * @param articleId 文章ID
     * @return 更新数量
     */
    int incrementLikeCount(@Param("articleId") Long articleId);

    /**
     * 减少文章点赞数
     * @param articleId 文章ID
     * @return 更新数量
     */
    int decrementLikeCount(@Param("articleId") Long articleId);

    /**
     * 增加文章收藏数
     * @param articleId 文章ID
     * @return 更新数量
     */
    int incrementCollectCount(@Param("articleId") Long articleId);

    /**
     * 减少文章收藏数
     * @param articleId 文章ID
     * @return 更新数量
     */
    int decrementCollectCount(@Param("articleId") Long articleId);

    /**
     * 添加用户点赞记录
     * @param userId 用户ID
     * @param articleId 文章ID
     * @return 是否成功添加
     */
    boolean addUserLike(@Param("userId") Long userId, @Param("articleId") Long articleId);

    /**
     * 移除用户点赞记录
     * @param userId 用户ID
     * @param articleId 文章ID
     * @return 是否成功移除
     */
    boolean removeUserLike(@Param("userId") Long userId, @Param("articleId") Long articleId);

    /**
     * 添加用户收藏记录
     * @param userId 用户ID
     * @param articleId 文章ID
     * @return 是否成功添加
     */
    boolean addUserCollect(@Param("userId") Long userId, @Param("articleId") Long articleId);

    /**
     * 移除用户收藏记录
     * @param userId 用户ID
     * @param articleId 文章ID
     * @return 是否成功移除
     */
    boolean removeUserCollect(@Param("userId") Long userId, @Param("articleId") Long articleId);

    /**
     * 检查用户是否已点赞文章
     * @param userId 用户ID
     * @param articleId 文章ID
     * @return 是否已点赞
     */
    Boolean checkUserLike(@Param("userId") Long userId, @Param("articleId") Long articleId);

    /**
     * 检查用户是否已收藏文章
     * @param userId 用户ID
     * @param articleId 文章ID
     * @return 是否已收藏
     */
    Boolean checkUserCollect(@Param("userId") Long userId, @Param("articleId") Long articleId);

    /**
     * 检查用户是否已关注文章作者
     * @param userId 用户ID
     * @param articleId 文章ID
     * @return 是否已关注作者
     */
    Boolean checkUserFollowAuthor(@Param("userId") Long userId, @Param("articleId") Long articleId);

    /**
     * 批量查询用户对文章的点赞状态
     * @param userId 用户ID
     * @param articleIds 文章ID列表
     * @return 已点赞的文章ID列表
     */
    List<Long> batchCheckUserLike(@Param("userId") Long userId, @Param("articleIds") List<Long> articleIds);

    /**
     * 批量查询用户对文章的收藏状态
     * @param userId 用户ID
     * @param articleIds 文章ID列表
     * @return 已收藏的文章ID列表
     */
    List<Long> batchCheckUserCollect(@Param("userId") Long userId, @Param("articleIds") List<Long> articleIds);

    /**
     * 更新文章评论数量（增量更新）
     * @param articleId 文章ID
     * @param increment 增量（可为负数）
     * @deprecated 已废弃，建议使用 recalculateArticleCommentCount 方法以确保数据一致性
     */
    @Deprecated
    void updateArticleCommentCount(@Param("articleId") Long articleId, @Param("increment") Integer increment);

    /**
     * 重新计算文章的评论数量（基于实际评论数）
     * @param articleId 文章ID
     */
    void recalculateArticleCommentCount(@Param("articleId") Long articleId);

    /**
     * 重新计算所有文章的评论数量
     */
    void recalculateAllArticleCommentCounts();


    // ==================== 标签相关方法 ====================

    /**
     * 更新文章的标签数量
     * @param articleId 文章ID
     * @param tagCount 标签数量
     * @return 更新数量
     */
    int updateArticleTagCount(@Param("articleId") Long articleId, @Param("tagCount") Integer tagCount);

    /**
     * 批量同步所有文章的标签数量
     * @return 更新数量
     */
    int syncAllArticleTagCounts();

    /**
     * 根据标签ID列表查询文章
     * @param page 分页对象
     * @param tagIds 标签ID列表
     * @return 文章列表
     */
    IPage<ArticleManagementResponse> selectArticlesByTagIds(Page<ArticleManagementResponse> page,
                                                           @Param("tagIds") List<Long> tagIds);

    /**
     * 查询包含所有指定标签的文章
     * @param page 分页对象
     * @param tagIds 标签ID列表
     * @return 文章列表
     */
    IPage<ArticleManagementResponse> selectArticlesByAllTags(Page<ArticleManagementResponse> page,
                                                            @Param("tagIds") List<Long> tagIds);

    // ==================== 用户端文章发布功能 ====================

    /**
     * 查询用户的文章列表
     * @param userId 用户ID
     * @param status 文章状态（可选）
     * @param offset 偏移量
     * @param size 每页大小
     * @return 用户文章列表
     */
    List<Article> selectUserArticles(@Param("userId") Long userId,
                                   @Param("status") Integer status,
                                   @Param("offset") Long offset,
                                   @Param("size") Long size);

    // ==================== SEO相关方法 ====================

    /**
     * 查询所有已发布的文章（用于生成sitemap）
     * @return 已发布文章列表
     */
    List<Article> selectPublishedArticlesForSitemap();
}
